package as3.component.controls
{
	import flash.display.DisplayObjectContainer;
	import flash.events.*;
	
	import as3.component.Component;
	import as3.component.event.ScrollEvent;
	import as3.component.geom.IntRectangle;
	import as3.component.support.ScrollArrowDown;
	import as3.component.support.ScrollArrowUp;
	import as3.component.support.ScrollThumb;
	
	public class ScrollBar extends Component
	{
		private var _direction:String = ScrollBarDirection.VERTICAL;
		private var _minScrollPosition:Number = 0;
		private var _pageSize:Number = 10;
		private var _maxScrollPosition:Number = 0;
		private var _lineScrollSize:Number = 1;
		private var _scrollPosition:Number = 0;
		private var thumbScrollOffset:Number;
		
		protected var downArrow:ScrollArrowDown;
		protected var upArrow:ScrollArrowUp;
		protected var track:DisplayObjectContainer;
		protected var thumb:ScrollThumb;
		protected var inDrag:Boolean = false;
		
		private var _pageScrollSize:Number = 0;
		public static const WIDTH:Number = 20;
		
		public function ScrollBar()
		{
			super();
		}
		
		override protected function initUI():void
		{
			super.initUI();
			_uiLibrary["trackBg"] = "ScrollTrack_skin";
		}
		
		override protected function initCom():void
		{
			super.initCom();
			
			setMasked(true);
			downArrow = new ScrollArrowDown();
			upArrow = new ScrollArrowUp();
			thumb = new ScrollThumb();
		}
		
		override protected function creatUI():void
		{
			super.creatUI();
			
			addChild(upArrow);
			track.width = upArrow.width;
			track.y = upArrow.height;
			addChild(track);
			thumb.setSize(thumb.width, 15);
			thumb.y = track.y;
			addChild(thumb);
			addChild(downArrow);
			upArrow.addEventListener(MouseEvent.MOUSE_DOWN, scrollPressHandler, false, 0, true);
			downArrow.addEventListener(MouseEvent.MOUSE_DOWN, scrollPressHandler, false, 0, true);
			track.addEventListener(MouseEvent.MOUSE_DOWN, scrollPressHandler, false, 0, true);
			thumb.addEventListener(MouseEvent.MOUSE_DOWN, thumbPressHandler, false, 0, true);			
			width = downArrow.width;
		}
		
		public function set trackBg(dis:DisplayObjectContainer):void
		{
			if (dis && track != dis) 
			{
				track = dis;
			}
		}
		
		override public function setSize(w:Number, h:Number):void
		{
			if (_direction == ScrollBarDirection.HORIZONTAL)
			{
				width = h;
			}
			else
			{
				height = h;
			}
			setMaskRect(new IntRectangle(0,0,width, height));
			return;
		}
		
		override public function set height(value:Number):void
		{
//			if (_direction == ScrollBarDirection.VERTICAL) super.height = value;
//			else super.width = value;
			super.height = value;
			setMaskRect(new IntRectangle(0,0,width, height));
			draw();
		}
		
		override public function set width(value:Number):void
		{
//			if (_direction == ScrollBarDirection.HORIZONTAL) super.width = value;
//			else super.height = value;
			super.width = value;
			setMaskRect(new IntRectangle(0,0,width, height));
			draw();
		}
		
		public function set lineScrollSize(value:Number):void
		{
			if (value > 0)
			{
				_lineScrollSize = value;
			}
			return;
		}
		
		public function get minScrollPosition() : Number
		{
			return _minScrollPosition;
		}
		
		protected function updateThumb():void
		{
			var _loc_1:* = _maxScrollPosition - _minScrollPosition + _pageSize;
			track.y = upArrow.height;
			if (track.height <= 12 || _maxScrollPosition <= _minScrollPosition || _loc_1 == 0 || isNaN(_loc_1))
			{
				thumb.height = 22;
				thumb.visible = false;
			}
			else
			{
				//thumb.height = Math.max(ScrollThumb.MIN_HEIGHT, _pageSize / _loc_1 * track.height);
				thumb.height = 22; //bug1702
				thumb.y = track.y + (track.height - thumb.height) * ((_scrollPosition - _minScrollPosition) / (_maxScrollPosition - _minScrollPosition));
				thumb.visible = true;
			}
			return;
		}
		
		public function set minScrollPosition(value:Number):void
		{
			setScrollProperties(_pageSize, value, _maxScrollPosition);
			return;
		}
		
		public function get lineScrollSize() : Number
		{
			return _lineScrollSize;
		}
		
		public function setScrollPosition(pos:Number, dispatch:Boolean = true):void
		{
			var _pos:Number = scrollPosition;
			_scrollPosition = Math.max(_minScrollPosition, Math.min(_maxScrollPosition, pos));
			if (_pos == _scrollPosition)
			{
				return;
			}
			if (dispatch)
			{
				dispatchEvent(new ScrollEvent(ScrollEvent.SCROLL, scrollPosition));
			}
			updateThumb();
			return;
		}
		
		public function get maxScrollPosition() : Number
		{
			return _maxScrollPosition;
		}
		
		public function get scrollPosition() : Number
		{
			return _scrollPosition;
		}
		
		override public function get height() : Number
		{
			return _direction == ScrollBarDirection.HORIZONTAL ? (super.width) : (super.height);
		}
		
		public function get pageSize() : Number
		{
			return _pageSize;
		}
		
		public function set maxScrollPosition(value:Number):void
		{
			setScrollProperties(_pageSize, _minScrollPosition, value);
			return;
		}
		
		protected function thumbReleaseHandler(evt:MouseEvent):void
		{
			inDrag = false;
			mouseChildren = true;
			if (stage)
			{
				stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleThumbDrag);
				stage.removeEventListener(MouseEvent.MOUSE_UP, thumbReleaseHandler);
			}
			return;
		}
		
		public function set pageScrollSize(value:Number):void
		{
			if (value >= 0)
			{
				_pageScrollSize = value;
			}
			return;
		}
		
		public function get pageScrollSize() : Number
		{
			return _pageScrollSize == 0 ? (_pageSize) : (_pageScrollSize);
		}
		
		public function set scrollPosition(value:Number):void
		{
			setScrollPosition(value, true);
			return;
		}
		
		protected function draw():void
		{
			var _loc_1:Number;
			_loc_1 = super.height;
			downArrow.move(0, Math.max(upArrow.height, _loc_1 - downArrow.height));
			track.height = Math.max(0, _loc_1 - (downArrow.height + upArrow.height));
			updateThumb();
			return;
		}
		
//		override public function get width() : Number
//		{
//			return _direction == ScrollBarDirection.HORIZONTAL ? (super.height) : (super.width);
//		}
		
		public function set pageSize(value:Number):void
		{
			if (value > 0)
			{
				_pageSize = value;
			}
			return;
		}
		
		public function setScrollProperties(pageSize:Number, minScrollPosition:Number, maxScrollPosition:Number, pageScrollSize:Number = 0):void
		{
			this.pageSize = pageSize;
			_minScrollPosition = minScrollPosition;
			_maxScrollPosition = maxScrollPosition;
			if (pageScrollSize >= 0)
			{
				_pageScrollSize = pageScrollSize;
			}
			setScrollPosition(_scrollPosition, false);
			updateThumb();
			return;
		}
		
		protected function handleThumbDrag(evt:MouseEvent):void
		{
			var _value:* = Math.max(0, Math.min(track.height - thumb.height, mouseY - track.y - thumbScrollOffset));
			setScrollPosition(_value / (track.height - thumb.height) * (_maxScrollPosition - _minScrollPosition) + _minScrollPosition);
			return;
		}
		
		protected function scrollPressHandler(evt:MouseEvent):void
		{
			var _loc_2:Number;
			var _loc_3:Number;
			evt.stopImmediatePropagation();
			if (evt.currentTarget == upArrow)
			{
				setScrollPosition(_scrollPosition - _lineScrollSize);
			}
			else if (evt.currentTarget == downArrow)
			{
				setScrollPosition(_scrollPosition + _lineScrollSize);
			}
			else
			{
				var g:Number = thumb.mouseY + thumb.y - track.y;
				_loc_2 = g / track.height * (_maxScrollPosition - _minScrollPosition) + _minScrollPosition;
				_loc_3 = pageScrollSize == 0 ? (pageSize) : (pageScrollSize);
				if (_scrollPosition < _loc_2)
				{
					setScrollPosition(Math.min(_loc_2, _scrollPosition + _loc_3));
				}
				else if (_scrollPosition > _loc_2)
				{
					setScrollPosition(Math.max(_loc_2, _scrollPosition - _loc_3));
				}
			}
			return;
		}
		
		protected function thumbPressHandler(evt:MouseEvent):void
		{
			inDrag = true;
			thumbScrollOffset = mouseY - thumb.y;
			mouseChildren = false;
			stage.addEventListener(MouseEvent.MOUSE_MOVE, handleThumbDrag, false, 0, true);
			stage.addEventListener(MouseEvent.MOUSE_UP, thumbReleaseHandler, false, 0, true);
			return;
		}
		
		public function set direction(value:String):void
		{
			if (_direction == value)
			{
				return;
			}
			_direction = value;
			scaleY = 1;
			var _loc_2:* = _direction == ScrollBarDirection.HORIZONTAL;
			if (_loc_2)
			{
				if (rotation == 90)
				{
					return;
				}
				scaleX = -1;
				rotation = -90;
			}
			if (!_loc_2)
			{
				if (_loc_2 && rotation == 0)
				{
					rotation = -90;
					scaleX = -1;
				}
				else if (!_loc_2 && rotation == -90)
				{
					rotation = 0;
					scaleX = 1;
				}
			}
			draw();
			return;
		}
		
		public function get direction() : String
		{
			return _direction;
		}
		
	}
}
